function getTimeText(time) {
	let h = Math.floor(time / 60)
	let m = Math.floor(time - h * 60)
	return (h ? h.toString() : 12) + ':' + (m < 10 ? ('0' + m.toString()) : m.toString()) + ' AM'
}

function createState() {
	return {
		state: 'on',
		time: 0,
		powerOutage: false,
		power: 100,

		leftDoorLight: false,
		leftDoorLightClicked: false,
		leftDoorClosed: false,
		leftDoorClosedClicked: false,
		leftDoorPosition: 0,

		rightDoorLight: false,
		rightDoorLightClicked: false,
		rightDoorClosed: false,
		rightDoorClosedClicked: false,
		rightDoorPosition: 0,

		at: 1,
		cameraOn: false,
		cameraButtonClicked: false,
		cameraAt: 12,

		cameraGlitch: .1,

		jumpscared: false,
		jumpscaredBy: undefined,
		jumpscaredTime: 0,

		antagonistIota: 12,
		antagonistIotaActiveness: 0,

		antagonistOmicron: 12,
		antagonistOmicronActiveness: 0,

		antagonistAlpha: 12,
		antagonistAlphaActiveness: 0,

		antagonistOmega: 5,
		antagonistOmegaStage: 0,
		antagonistOmegaMovement: 0,
		antagonistOmegaActiveness: 0,
	}
}

function calculatePowerUsage(config, state) {
	let powerConsume = 1
	if (state.leftDoorLight)
		powerConsume += 1
	if (state.leftDoorClosed)
		powerConsume += 1
	if (state.rightDoorLight)
		powerConsume += 1
	if (state.rightDoorClosed)
		powerConsume += 1
	if (state.cameraOn)
		powerConsume += 1
	return powerConsume
}

function updateState(config, state, elapsed) {
	// Calculate elapsed time
	let timeElapsed = elapsed * config.minutesPerMS

	// Handle win
	if (state.state == 'win')
		return

	// Handle jumpscare
	if (state.state == 'lose') {
		if (state.jumpscaredTime < 3)
			state.jumpscaredTime += timeElapsed
		else
			gameState = 'lose'
		return
	}

	// Advance game time
	state.time += timeElapsed
	if (state.time >= 360) {
		state.state = 'win'
		gameWin()
		return
	}
	state.cameraGlitch = Math.max(state.cameraGlitch - 50 * timeElapsed, .1)

	// Update power
	if (state.powerOutage) {
		state.power = 0
		state.leftDoorLight = false
		state.leftDoorClosed = false
		state.rightDoorLight = false
		state.rightDoorClosed = false
		state.cameraOn = false
	} else {
		let powerConsume = calculatePowerUsage(config, state)
		if ((state.power -= powerConsume * timeElapsed * config.powerConsumePerMinute) <= 0)
			state.powerOutage = true
	}

	// Update door position
	if (state.leftDoorClosed)
		state.leftDoorPosition = Math.min(state.leftDoorPosition + 5 * timeElapsed, 1)
	else
		state.leftDoorPosition = Math.max(state.leftDoorPosition - 5 * timeElapsed, 0)
	if (state.rightDoorClosed)
		state.rightDoorPosition = Math.min(state.rightDoorPosition + 5 * timeElapsed, 1)
	else
		state.rightDoorPosition = Math.max(state.rightDoorPosition - 5 * timeElapsed, 0)

	// Update antagonist activeness and position
	let nextRoomList = {
		5: [6],
		6: [3, 5, 7],
		7: [6, 8],
		8: [4, 7],
		10: [6, 7, 8],
		11: [6, 10],
		12: [10, 11, 13],
		13: [8, 10]
	}
	if (config.iota) {
		// Update Iota
		let updatedActiveness = config.iota * timeElapsed
		if (state.antagonistIota <= 4) {
			if ((state.antagonistIota == 3) ? state.leftDoorClosed : state.rightDoorClosed) {
				state.antagonistIotaActiveness -= updatedActiveness
			} else
				state.antagonistIotaActiveness += updatedActiveness
			if (state.antagonistIotaActiveness >= 100) {
				// Jumpscared by Iota
				state.antagonistIota = 1
				state.state = 'lose'
				state.jumpscared = true
				state.jumpscaredBy = 'iota'
				state.jumpscaredTime = 0
			} else if (state.antagonistIotaActiveness <= -50) {
				// Iota failed to jumpscare
				state.antagonistIota = 12
				state.antagonistIotaActiveness = 0
			}
		} else {
			state.antagonistIotaActiveness += updatedActiveness
			if (state.antagonistIotaActiveness >= 200) {
				// Iota moves
				state.antagonistIotaActiveness -= 200
				let possibleMoves = nextRoomList[state.antagonistIota]
				state.antagonistIota = possibleMoves[Math.floor(Math.random() * possibleMoves.length)]
				state.cameraGlitch = 100
				playAudio('assets/sound/footstep.ogg')
			}
		}
	}
	if (config.omicron) {
		// Update Omicron
		let updatedActiveness = config.omicron * timeElapsed
		if (state.antagonistOmicron <= 4) {
			if ((state.antagonistOmicron == 3) ? state.leftDoorClosed : state.rightDoorClosed) {
				state.antagonistOmicronActiveness -= updatedActiveness
			} else
				state.antagonistOmicronActiveness += updatedActiveness
			if (state.antagonistOmicronActiveness >= 200) {
				// Jumpscared by Omicron
				state.antagonistOmicron = 1
				state.state = 'lose'
				state.jumpscared = true
				state.jumpscaredBy = 'omicron'
				state.jumpscaredTime = 0
			} else if (state.antagonistOmicronActiveness <= -50) {
				// Omicron failed to jumpscare
				state.antagonistOmicron = 12
				state.antagonistOmicronActiveness = 0
			}
		} else {
			state.antagonistOmicronActiveness += updatedActiveness
			if (state.antagonistOmicronActiveness >= 100) {
				// Omicron moves
				state.antagonistOmicronActiveness -= 100
				let possibleMoves = nextRoomList[state.antagonistOmicron]
				state.antagonistOmicron = possibleMoves[Math.floor(Math.random() * possibleMoves.length)]
				state.cameraGlitch = 100
				playAudio('assets/sound/footstep.ogg')
			}
		}
	}
	if (config.alpha) {
		// Update Alpha
		let updatedActiveness = config.alpha * timeElapsed
		if (state.antagonistAlpha <= 4) {
			if ((state.antagonistAlpha == 3) ? state.leftDoorClosed : state.rightDoorClosed) {
				state.antagonistAlphaActiveness -= updatedActiveness
			} else
				state.antagonistAlphaActiveness += updatedActiveness
			if (state.antagonistAlphaActiveness >= 200) {
				// Jumpscared by Alpha
				state.antagonistAlpha = 1
				state.state = 'lose'
				state.jumpscared = true
				state.jumpscaredBy = 'alpha'
				state.jumpscaredTime = 0
			} else if (state.antagonistAlphaActiveness <= -50) {
				// Alpha failed to jumpscare
				state.antagonistAlpha = 12
				state.antagonistAlphaActiveness = 0
			}
		} else {
			state.antagonistAlphaActiveness += updatedActiveness
			if (state.antagonistAlphaActiveness >= 200) {
				// Alpha moves
				state.antagonistAlphaActiveness -= 200
				let possibleMoves = nextRoomList[state.antagonistAlpha]
				state.antagonistAlpha = possibleMoves[Math.floor(Math.random() * possibleMoves.length)]
				state.cameraGlitch = 100
				playAudio('assets/sound/footstep.ogg')
			}
		}
	}
	if (config.omega) {
		// Update Omega
		let updatedActiveness = config.omega * timeElapsed
		if (state.antagonistOmega <= 4) {
			if ((state.antagonistOmega == 3) ? state.leftDoorClosed : state.rightDoorClosed) {
				state.antagonistOmegaActiveness -= updatedActiveness
			} else
				state.antagonistOmegaActiveness += updatedActiveness
			if (state.antagonistOmegaActiveness >= 20) {
				// Jumpscared by Omega
				state.antagonistOmega = 1
				state.state = 'lose'
				state.jumpscared = true
				state.jumpscaredBy = 'omega'
				state.jumpscaredTime = 0
			} else if (state.antagonistOmegaActiveness <= -20) {
				// Omega failed to jumpscare
				state.antagonistOmega = 5
				state.antagonistOmegaActiveness = 0
			}
		} else {
			state.antagonistOmegaActiveness += updatedActiveness
			// Omega moves
			if (state.antagonistOmegaActiveness >= 1000) {
				state.antagonistOmegaActiveness -= 1000
				state.antagonistOmega = (Math.random() < .6) ? 3 : 4
			} else if (state.antagonistOmegaActiveness >= 950) {
				if (state.antagonistOmega == 5) {
					state.antagonistOmega = 6
					playAudio('assets/sound/run.ogg')
				}
				state.antagonistOmegaMovement = (state.antagonistOmegaActiveness - 950) * .02
			} else {
				state.antagonistOmega = 5
				state.antagonistOmegaStage = (state.antagonistOmegaActiveness >= 800) ? 2 : ((state.antagonistOmegaActiveness >= 500) ? 1 : 0)
			}
		}
	}
	// Play jumpscare music
	if (state.jumpscared) {
		stopAllAudio()
		playAudio('assets/sound/end.ogg', true)
	}
}